package svgedit.gui.actions;

import java.util.ArrayList;
import java.util.Iterator;

import svgedit.gui.View;
import svgedit.svg.SVGElement;
import svgedit.svg.SVGGroup;
import svgedit.svg.SVGRootGroup;

/**
 * This class store the current shapes selected in the editor
 * 
 * @author SARJ
 */
public class SelectedElements implements Iterable<SVGElement>
{
	private static final long serialVersionUID = 4692535727215569453L;
	private ArrayList<SVGElement> selectedElements;
	private View view;

	/**
	 * Creates a SelectedElements class for the specified view.
	 * 
	 * @param view
	 *            The view that the elements are being selected in
	 */
	public SelectedElements(View view)
	{
		this.selectedElements = new ArrayList<SVGElement>();
		this.view = view;
	}

	public Iterator<SVGElement> iterator()
	{
		return this.selectedElements.iterator();
	}

	/**
	 * Clears the list of selected elements
	 */
	public void clear()
	{
		selectedElements.removeAll(selectedElements);
	}

	/**
	 * Adds the supplied elements to the selected elements list
	 * 
	 * @param element
	 *            to be added to the list
	 * @return number of elements in the list after the supplied was added
	 */
	public int add(SVGElement element)
	{
		SVGGroup group = element.getParent();
		if (group instanceof SVGRootGroup)
		{
			if (!this.selectedElements.contains(element))
				this.selectedElements.add(element);

			return this.size();
		}

		while (!(group.getParent() instanceof SVGRootGroup))
			group = group.getParent();

		System.out.println("SelectedElements.add group" + group);

		// add element's group to selected elements
		if (!this.selectedElements.contains(group))
			this.selectedElements.add(group);

		// if adding a group remove any of its children from selected
		if (element instanceof SVGGroup)
			for (SVGElement e : this.selectedElements)
				if (e.getParent() == element)
					this.selectedElements.remove(e);

		return this.size();
	}

	/**
	 * Removed the supplied element from the selection list 
	 * @param element to be removed from selection
	 * @return number of elements selected after element is removed
	 */
	public int remove(SVGElement element)
	{
		if (element instanceof SVGGroup)
		{
			// add group members to selection
			for (SVGElement child : ((SVGGroup) element))
				remove(child);
			this.selectedElements.remove(element);
		}
		else
		{
			this.selectedElements.remove(element);
		}
		view.repaint();
		return this.size();
	}

	/**
	 * Returns the last 
	 * @return A reference to the list of elements
	 */
	public ArrayList<SVGElement> getList()
	{
		return this.selectedElements;
	}

	/**
	 * Used to determined if the current selection includes groups
	 * @return true if the selection includes a group. False if not.
	 */
	public boolean includesGroups()
	{
		// System.out.println("SelectedElements.includesGroups checking selected includes groups");
		for (SVGElement element : selectedElements)
			if (element instanceof SVGGroup)
				return true;
		return false;
	}

	/**
	 * Used to determine if the supplied element is in the current selected
	 * elements list
	 * 
	 * @param element to test to see if is selected
	 * @return true if the element is selected
	 */
	public boolean contains(SVGElement element)
	{
		return this.selectedElements.contains(element);
	}

	/**
	 * Returns the number of elements currently selected.
	 * @return The amount of elements selected
	 */
	public int size()
	{
		return this.selectedElements.size();
	}

}
